package ru.spb.osll.myfit.client.view;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import ru.spb.osll.myfit.client.PageMode;
import ru.spb.osll.myfit.client.event.PageButtonEvent;
import ru.spb.osll.myfit.client.event.PageButtonEvent.PageButtonEventType;
import ru.spb.osll.myfit.client.event.PageEvent;
import ru.spb.osll.myfit.client.event.PageEvent.PageEventType;
import ru.spb.osll.myfit.client.manager.PageExecutingManager;
import ru.spb.osll.myfit.client.service.FitServiceAsync;
import ru.spb.osll.myfit.client.widget.*;
import ru.spb.osll.myfit.common.Page;
import ru.spb.osll.myfit.common.PageElement;

import java.util.LinkedList;
import java.util.List;

public class MyFitView extends AbstractView {

  private Panel m_viewModePanel;

  private Panel m_editModePanel;

  private String m_pagePath;

  private PageMode mode;

  private final Anchor anch;

  private PageWidget m_pageWidget;

  private PageExecutingManager m_executingManager = new PageExecutingManager();

  private PageButtonEventListener m_buttonEventListener;

  private FitServiceAsync m_fitService;

  private ProgressBar myProgressBar;
  private ProgressLabel myProgressLabel;
  
  private boolean isTestStarted = false;
  
  public MyFitView(String address, PageWidget pageWidget,
                   FitServiceAsync fitService) {
    m_buttonEventListener = createButtonEventListener();
    m_fitService = fitService;
    m_pagePath = address;
    m_pageWidget = pageWidget;
    mode = PageMode.VIEW;
    anch = new Anchor(getTitleName());
    pageWidget.setMode(mode);
    createRootPanel();
  }

  private PageButtonEventListener createButtonEventListener() {
    PageButtonEventListener listener = new PageButtonEventListener() {

      @Override
      public void actionPerformed(PageButtonEvent event) {
        switch (event.getType()) {
        case ADD_TABLE:
          m_pageWidget.actionPerformed(new PageEvent(PageEventType.ADD_TABLE));
          break;
        case ADD_INLUDE:
          m_pageWidget
              .actionPerformed(new PageEvent(PageEventType.ADD_INCLUDE));
          break;
        case ADD_WIKI:
          m_pageWidget.actionPerformed(new PageEvent(PageEventType.ADD_WIKI));
          break;
        case ADD_CONTENT:
          m_pageWidget
              .actionPerformed(new PageEvent(PageEventType.ADD_CONTENT));
          break;
        case COLLAPSE_ALL:
          m_pageWidget.setOpen(false);
          break;
        case EXPAND_ALL:
          m_pageWidget.setOpen(true);
          break;
        case SAVE_PAGE:
          savePage(m_pagePath, m_pageWidget.getPage());
          break;
        case TEST_PAGE:
          executeTestPage();
          break;
        case REFRESH:
          com.google.gwt.user.client.Window.Location.reload();
          break;
        case LIST_OF_EXECUTING_TEST:
          Window.open(ViewConstants.TEST_RESULTS_VIEW_NAME, "", "");
          break;

        default:
          break;
        }
      }
    };
    return listener;
  }

  @Override
  protected void createEditPanel() {
    super.createEditPanel();
    anch.setStyleName("editTitleText");
    anch.addClickHandler(new ClickHandler() {

      @Override
      public void onClick(ClickEvent event) {
        if (mode.equals(PageMode.EDIT)) {
          mode = PageMode.VIEW;
          m_editPanel.remove(m_editModePanel);
          m_editPanel.add(m_viewModePanel);
        } else if (!isTestStarted) {
          mode = PageMode.EDIT;
          m_editPanel.remove(m_viewModePanel);
          m_editPanel.add(m_editModePanel);
        }
        anch.setText(getTitleName());
        m_pageWidget.setMode(mode);
      }
    });
    m_editPanel.add(anch);

    createEditModePanel();
    createViewModePanel();
    if (mode.equals(PageMode.EDIT)) {
      m_editPanel.add(m_editModePanel);
    } else {
      m_editPanel.add(m_viewModePanel);
    }
  }

  private void createEditModePanel() {
    m_editModePanel = new VerticalPanel();
    ((VerticalPanel) m_editModePanel)
        .setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
    HorizontalPanel hPanel = new HorizontalPanel();
    hPanel.setSpacing(5);
    hPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
    hPanel.add(new PageButton("Save page", "sendButtonStyle",
        PageButtonEventType.SAVE_PAGE, m_buttonEventListener));
    HorizontalPanel separator = new HorizontalPanel();
    separator.setWidth("20");
    hPanel.add(separator);

    hPanel.add(new PageButton("Expand all", "expandAllIncludesButtonStyle",
        PageButtonEventType.EXPAND_ALL, m_buttonEventListener));
    hPanel.add(new PageButton("Collapse all", "collapseAllIncludesButtonStyle",
        PageButtonEventType.COLLAPSE_ALL, m_buttonEventListener));
    hPanel.add(new PageButton("Discard", "discardButtonStyle",
        PageButtonEventType.REFRESH, m_buttonEventListener));
    hPanel.add(new PageButton("Add table", "addTableButtonStyle",
        PageButtonEventType.ADD_TABLE, m_buttonEventListener));
    hPanel.add(new PageButton("Include page", "importPageButtonStyle",
        PageButtonEventType.ADD_INLUDE, m_buttonEventListener));
    hPanel.add(new PageButton("Input text", "textInputButtonStyle",
        PageButtonEventType.ADD_WIKI, m_buttonEventListener));
    hPanel.add(new PageButton("Add content", "addContentButtonStyle",
        PageButtonEventType.ADD_CONTENT, m_buttonEventListener));
    m_editModePanel.add(hPanel);
  }

  private void createViewModePanel() {
    m_viewModePanel = new HorizontalPanel();
    m_viewModePanel.setWidth("100%");

    HorizontalPanel hPanel = new HorizontalPanel();
    hPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
    hPanel.setSpacing(5);

    hPanel.add(new PageButton("Test page", "testButtonStyle",
        PageButtonEventType.TEST_PAGE, m_buttonEventListener));
    HorizontalPanel separator = new HorizontalPanel();
    separator.setWidth("20");
    hPanel.add(separator);
    hPanel.add(new PageButton("Expand all", "expandAllIncludesButtonStyle",
        PageButtonEventType.EXPAND_ALL, m_buttonEventListener));
    hPanel.add(new PageButton("Collapse all", "collapseAllIncludesButtonStyle",
        PageButtonEventType.COLLAPSE_ALL, m_buttonEventListener));
    hPanel.add(new PageButton("list of executing test",
        "listOfExecutingTestButtonStyle",
        PageButtonEventType.LIST_OF_EXECUTING_TEST, m_buttonEventListener));

    HorizontalPanel right = new HorizontalPanel();
    right.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
    right.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
    right.setSpacing(5);
    myProgressBar = new ProgressBar();
    myProgressLabel = new ProgressLabel();
    right.setWidth("100%");
    right.add(myProgressLabel);
    right.add(myProgressBar);
    right.setCellWidth(myProgressBar, "250px");
    m_viewModePanel.add(hPanel);
    m_viewModePanel.add(right);
  }

  @Override
  protected Widget createContentPanel() {
    return m_pageWidget;
  }

  public void setPagePath(String pagePath) {
    m_pagePath = pagePath;
    m_pageWidget.setPagePath(m_pagePath);
    anch.setText(getTitleName());
  }

  private String getTitleName() {
    String title;
    String path = "";
    if (!m_pagePath.isEmpty()) {
      path = "\"" + m_pagePath + "\"";
    }

    if (mode == PageMode.VIEW) {
      title = PageMode.EDIT.toString() + "   " + path;
    } else {
      title = PageMode.VIEW.toString() + "   " + path;
    }
    return title;
  }

  public void addPageElementWidget(PageElement element) {
    m_pageWidget.addPageElementWidget(element);
  }

  public void savePage(String path, Page page) {
    m_fitService.savePage(path, page, new AsyncCallback<Object>() {
      public void onFailure(final Throwable caught) {
        // m_errorDialog.setText(caught.getMessage());
        // m_errorDialog.center();
      }

      public void onSuccess(final Object result) {

      }
    });
  }
  
  private void executeTestPage(){
    isTestStarted = true;
    myProgressBar.setVisible(true);
    myProgressLabel.setVisible(true);
    List<PageExecutingListener> listeners = new LinkedList<PageExecutingListener>();
    listeners.add(new PageExecutingListenerImpl(m_pageWidget));
    listeners.add(myProgressBar);
    listeners.add(myProgressLabel);
    m_executingManager.executeTestPage(listeners, m_pagePath);
  }
}
